package router

import (
	"context"
	"fmt"
	"shop-manager/internal/do"
	"shop-manager/internal/logic"
	"shop-manager/internal/repos/category"
	"shop-manager/internal/vo"

	"github.com/gin-gonic/gin"
)

func checkCatetoryMetaId(ctx context.Context, categoryRepo *category.CategoryRepo, classId, levelId, brandId int) error {
	categoryMetaMap, err := categoryRepo.GetCategoryMetaMap(ctx, category.ListCategoryMetaParam{
		IDs: []int{classId, levelId, brandId},
	})
	if err != nil {
		return err
	}
	if _, ok := categoryMetaMap[classId]; !ok {
		return fmt.Errorf("分类不存在: %d", classId)
	}
	if _, ok := categoryMetaMap[levelId]; !ok {
		return fmt.Errorf("等级不存在: %d", levelId)
	}
	if _, ok := categoryMetaMap[brandId]; !ok {
		return fmt.Errorf("品牌不存在: %d", brandId)
	}

	return nil
}

func RegisterCategory(api *gin.RouterGroup,
	categoryRepo *category.CategoryRepo,
	categoryLogic *logic.CategoryLogic,
	handleBizRsp func(ctx *gin.Context, rsp any, err error),
	handleBizListRsp func(ctx *gin.Context, rsp any, total int64, err error),
) {
	categoryApiGroup := api.Group("/category")
	{
		categoryApiGroup.POST("/create", func(ctx *gin.Context) {
			type ReqJson struct {
				ClassID int
				LevelID int
				BrandID int
			}
			var req ReqJson
			if err := ctx.BindJSON(&req); err != nil {
				return
			}

			// 检查参数
			if err := checkCatetoryMetaId(ctx, categoryRepo, req.ClassID, req.LevelID, req.BrandID); err != nil {
				handleBizRsp(ctx, 0, err)
				return
			}

			id, err := categoryRepo.CreateCategory(ctx, &do.Category{
				ClassID: req.ClassID,
				LevelID: req.LevelID,
				BrandID: req.BrandID,
			})
			handleBizRsp(ctx, map[string]any{
				"id": id,
			}, err)
		})

		categoryApiGroup.POST("/update", func(ctx *gin.Context) {
			type ReqJson struct {
				ID      int
				ClassID int
				LevelID int
				BrandID int
			}
			var req ReqJson
			if err := ctx.BindJSON(&req); err != nil {
				return
			}

			// 检查参数
			if err := checkCatetoryMetaId(ctx, categoryRepo, req.ClassID, req.LevelID, req.BrandID); err != nil {
				handleBizRsp(ctx, 0, err)
				return
			}

			err := categoryRepo.UpdateCategory(ctx, &do.Category{
				ID:      req.ID,
				ClassID: req.ClassID,
				LevelID: req.LevelID,
				BrandID: req.BrandID,
			})
			handleBizRsp(ctx, nil, err)
		})

		categoryApiGroup.POST("/delete", func(ctx *gin.Context) {
			type ReqJson struct {
				ID int
			}
			var req ReqJson
			if err := ctx.BindJSON(&req); err != nil {
				return
			}
			// TODO 检查是否被引用
			err := categoryRepo.DeleteCategory(ctx, req.ID)
			handleBizRsp(ctx, nil, err)
		})

		categoryApiGroup.POST("/list", func(ctx *gin.Context) {
			var req vo.ListCategoryReq
			if err := ctx.BindJSON(&req); err != nil {
				return
			}
			listData, err := categoryLogic.ListCategory(ctx, req)
			handleBizRsp(ctx, listData, err)
		})
	}
}
